/**
 * 
 */
package info.niwota.profile.contact;

import info.niwota.profile.Debug;
import info.niwota.profile.R;

import java.util.ArrayList;
import java.util.Iterator;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.AsyncTask;
import android.os.Bundle;
import android.util.Log;
import android.util.SparseBooleanArray;
import android.view.KeyEvent;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.ListView;

/**
 * @author qiangli
 * 
 */
public class RecipientsActivity extends ListActivity implements OnClickListener {

	private class InitTask extends AsyncTask<Void, Void, Void> {

		@Override
		protected void onCancelled() {
			setProgressBarIndeterminateVisibility(false);
		}

		@Override
		protected void onPreExecute() {
			setProgressBarIndeterminateVisibility(true);
		}

		@Override
		protected Void doInBackground(Void... params) {
			loadAddresses();
			return null;
		}

		@Override
		protected void onPostExecute(Void result) {
			try {
				updateUi();
			} finally {
				setProgressBarIndeterminateVisibility(false);
			}
		}
	}

	//private static final int DIALOG_SAVEAS = 1;
	
	private static final String TAG = "RecipientsActivity";
	
	private static final int DIALOG_VIEWSELECTED = 2;

	public static final String EXTRA_EMAILS = "extra.emails";
	
	//private static final int RC_VOICEINPUT_SAVEAS = 1;
	
	private ArrayAdapter<EmailAddress> adapter;

	private ArrayList<EmailAddress> addresses = new ArrayList<EmailAddress>();
	// set to new list name if list is selected/created,
	// clear if select all, none, other or any item is un/checked
	private String listname;
	
	private EmailAddress[] emailList;

	//
	//private EditText editName;
	//private TextView recipientsText;
	//private MenuItem saveasMenuItem;
	//private MenuItem selectMenuItem;
	//private View buttons;
	//private View footer;
	//private MenuItem exportMenuItem;
	//private MenuItem importMenuItem;
	//private boolean restored;
//	private RadioButton starButton0;
//	private RadioButton starButton1;
//	private RadioButton starButton2;
	
	//private ArrayList<String> listNames;
	
	private MenuItem viewMenuItem;
	private ArrayAdapter<NameIndex> viewSelectedItems;
	private Button btnOk;
	private Button btnCancel;
	
	private void doLists(String n) {
		String[] emails = ContactUtils.getEmail(this, n);
		int len = emails.length;
		//
		ListView v = getListView();
		v.clearChoices();
		int pos = 0;
		//
		for (EmailAddress a : addresses) {
			boolean ck = false;
			if (len != 0) {
				String ea = a.address;
				for (int i = 0; i < len; i++) {
					if (emails[i].equals(ea)) {
						ck = true;
						break;
					}
				}
			}
			v.setItemChecked(pos++, ck);
		}
		//
		listname = n;
		//
		refreshUi(v, true, n);
	}

//	/*
//	 * save new list
//	 */
//	private void doSave(String name, int star) {
//		ArrayList<EmailAddress> al = getSelectedEmails();
//		String[] emails = Utils.toStringArray(al);
//		name = Utils.ensureListName(name);
//		
////		if (contact) {
////			ContactUtils.saveAsContact(this, name, star, emails);
////		} else {
////			ContactUtils.addList(this, name, star, emails);
////		}
//
//		ContactUtils.addList(this, name, star, emails);
//		
//		listname = name;
//		//
//		ListView v = getListView();
//		refreshUi(v, false, name);
//	}

	/*
	 * Select all, none, or other
	 * 
	 * @param id
	 */
	private void doSelect(int id) {
		// clear listname
		listname = null;
		//
		final ListView v = getListView();
		switch (id) {
		case R.id.recipients_select_none_menu_id: {
			v.clearChoices();
			refreshUi(v, false, null); // donot show action as there is no
			// selection
			return;
		}
		case R.id.recipients_select_all_menu_id: {
			int cnt = v.getCount();
			for (int i = 0; i < cnt; i++) {
				v.setItemChecked(i, true);
			}
			refreshUi(v, true, null);
			return;
		}
		case R.id.recipients_select_other_menu_id: {
			int cnt = v.getCount();
			for (int i = 0; i < cnt; i++) {
				boolean ck = v.isItemChecked(i);
				v.setItemChecked(i, !ck);
			}
			refreshUi(v, true, null);
			return;
		}
		}
	}

	private int getCount() {
		return adapter.getCount();
	}

	private int getSelectedCount() {
		SparseBooleanArray ps = getListView().getCheckedItemPositions();
		int size = adapter.getCount();
		int cnt = 0;
		for (int i = 0; i < size; i++) {
			if (ps.get(i)) {
				cnt++;
			}
		}
		return cnt;
	}

	private ArrayList<EmailAddress> getSelectedEmails() {
		SparseBooleanArray ps = getListView().getCheckedItemPositions();
		ArrayList<EmailAddress> ck = new ArrayList<EmailAddress>();
		int size = adapter.getCount();
		for (int i = 0; i < size; i++) {
			if (ps.get(i)) {
				ck.add(adapter.getItem(i));
			}
		}
		return ck;
	}

	private boolean hasSelected() {
		SparseBooleanArray ps = getListView().getCheckedItemPositions();
		int size = adapter.getCount();
		for (int i = 0; i < size; i++) {
			if (ps.get(i)) {
				return true;
			}
		}
		return false;
	}

	private void updateUi() {
		// set to reload
		getListView().setAdapter(adapter);
		//
		EmailAddress[] el = emailList;
		ListView v = getListView();
		v.clearChoices();
		int pos = 0;
		for (EmailAddress a : addresses) {
			boolean ck = false;
			if (el != null) {
				for (int i = 0; i < el.length; i++) {
					if (el[i].equals(a)) {
						ck = true;
						break;
					}
				}
			}
			v.setItemChecked(pos++, ck);
		}
		// do not show actions unless triggered by user
		refreshUi(v, false, listname);
	}

	private void loadAddresses() {
		ContactUtils.loadAddresses(this, addresses);
		// merge addresses from intent
		if (emailList != null) {
			for (EmailAddress a : emailList) {
				if (!addresses.contains(a)) {
					addresses.add(a);
				}
			}
		}
	}

	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		if (Debug.DEBUG) {
			Log.d(TAG, "onCreate: " + savedInstanceState);
		}
		//
		requestWindowFeature(Window.FEATURE_INDETERMINATE_PROGRESS);
		requestWindowFeature(Window.FEATURE_LEFT_ICON);
		setContentView(R.layout.recipients);
		//
		adapter = new ArrayAdapter<EmailAddress>(this,
				R.layout.recipients_item_multiple_choice, addresses);

		setProgressBarIndeterminate(true);
		//
		final ListView lv = getListView();
		lv.setAdapter(adapter);
		lv.setItemsCanFocus(false);
		lv.setChoiceMode(ListView.CHOICE_MODE_MULTIPLE);
		//
		setTitle(R.string.action_friends);
		
		getWindow().setFeatureDrawableResource(Window.FEATURE_LEFT_ICON,
				R.drawable.ic_icon_32);
		//
		View buttons = findViewById(R.id.buttons);
		buttons.setVisibility(View.VISIBLE);
		btnOk = (Button) findViewById(R.id.button_ok);
		btnCancel = (Button) findViewById(R.id.button_cancel);
		btnOk.setOnClickListener(this);
		btnCancel.setOnClickListener(this);
		//
		//footer = findViewById(R.id.footer);
		//
		addresses.clear();
		if (savedInstanceState != null) {
			restore();
			updateUi();
		} else {
			init();
			new InitTask().execute();
		}
		//
		if (Debug.DEBUG) {
			Log.d(TAG, "listname: " + listname + " emailList: " + emailList);
		}
	}

	@SuppressWarnings("unchecked")
	private void restore() {
		Object[] obj = (Object[]) getLastNonConfigurationInstance();
		listname = (String) obj[0];
		ArrayList<EmailAddress> el = (ArrayList<EmailAddress>) obj[1];
		emailList = (el == null ? null : el.toArray(new EmailAddress[0]));
		ArrayList<EmailAddress> al = (ArrayList<EmailAddress>) obj[2];
		if (al != null) {
			addresses.addAll(al);
		}
	}

	private void init() {
		try {
			addresses.clear();
			//
			Intent i = getIntent();
			if (i == null) {
				return;
			}
			Bundle extras = i.getExtras();
			if (extras == null) {
				return;
			}
			// listname
			//listname = (String) extras.get(EtalkIntent.EXTRA_LISTNAME);

			// email list
			String emails = (String) extras.get(EXTRA_EMAILS);
			if (emails == null) {
				return;
			}
			emailList = toEmailAddress(emails);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

	private EmailAddress[] toEmailAddress(String emails)
			throws Exception {
		//InternetAddress[] list = InternetAddress.parse(emails);
		String[] list = emails.split(",");
		
		int len = list.length;
		EmailAddress[] al = new EmailAddress[len];
		for (int ix = 0; ix < len; ix++) {
			//InternetAddress ia = list[ix];
			//al[ix] = new EmailAddress(ia.getAddress(), ia.getPersonal());
			al[ix] = new EmailAddress(list[ix]);
		}
		return al;
	}

	@Override
	protected Dialog onCreateDialog(int id) {
		switch (id) {
		case DIALOG_VIEWSELECTED:
			return createViewSelectedDialog();
		default:
		}
		return null;
	}

	private Dialog createViewSelectedDialog() {
		final AlertDialog.Builder b = new AlertDialog.Builder(this);
		b.setTitle(R.string.title_my_friends_selected);
		
		viewSelectedItems = new ArrayAdapter<NameIndex>(
				this, R.layout.index_dialog_item);
		b.setAdapter(viewSelectedItems, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog, int which) {
				NameIndex i = (NameIndex) viewSelectedItems.getItem(which);
				if (i == null) {
					return;
				}
				ListView v = getListView();
				v.setSelected(false);
				v.setSelection(i.pos);
			}
		});
		final AlertDialog d = b.create();
		return d;
	}

	@Override
	public boolean onCreateOptionsMenu(Menu menu) {
		MenuInflater inflater = getMenuInflater();
		inflater.inflate(R.menu.recipients_options, menu);

		viewMenuItem = menu.findItem(R.id.recipients_view_menu_id);
		//selectMenuItem = menu.findItem(R.id.recipients_select_menu_id);
		//
		return true;
	}

	@Override
	public boolean onKeyDown(int keyCode, KeyEvent event) {
		if (keyCode == KeyEvent.KEYCODE_BACK) {
			doCancel();
			return true;
		} else {
			return super.onKeyDown(keyCode, event);
		}
	}

	private void doCancel() {
		setResult(RESULT_CANCELED);
		finish();
	}

	private void doFinish() {
		Intent data = new Intent();
		ArrayList<EmailAddress> emails = getSelectedEmails();
		if (emails.size() > 0) {
			data.putExtra(EXTRA_EMAILS, toString(emails));
		}
//		if (listname != null) {
//			data.putExtra(EtalkIntent.EXTRA_LISTNAME, listname);
//		}
		//
		setResult(RESULT_OK, data);
		finish();
		//
		if (Debug.DEBUG) {
			Log.d(TAG, "doFinish " + data);
		}
	}

	public static String toString(ArrayList<EmailAddress> emails) {
		if (emails == null) {
			return null;
		}
		Iterator<EmailAddress> i = emails.iterator();
		if (!i.hasNext()) {
			return null;
		}
		EmailAddress a = i.next();
		StringBuilder sb = new StringBuilder(a.address);
		while (i.hasNext()) {
			a = i.next();
			sb.append(", ");
			sb.append(a.address);
		}
		return sb.toString();
	}


	@Override
	protected void onListItemClick(ListView l, View v, int position, long id) {
		// list name and emails out of sync, clear it
		listname = null;
		//
		int sc = getSelectedCount();
		updateTitle(sc, listname);
		showOrHideActions(sc > 0);
	}

	private void showActions() {
		btnOk.setEnabled(true);
		//buttons.setVisibility(View.VISIBLE);
		//footer.setVisibility(View.GONE);
	}

	private void hideActions() {
		btnOk.setEnabled(false);
		//buttons.setVisibility(View.GONE);
		//footer.setVisibility(View.VISIBLE);
	}

	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
//		if (resultCode == RESULT_OK) {
//			switch(requestCode) {
//			default:
//			}
//		}
	}

	public void onClick(View v) {
		int id = v.getId();
		switch (id) {
		case R.id.button_ok:
			doFinish();
			break;
		case R.id.button_cancel:
			doCancel();
			break;
		}
	}

	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		int id = item.getItemId();
		switch (id) {
		case R.id.recipients_view_menu_id:
			doViewSelected();
			break;
		case R.id.recipients_select_all_menu_id:
		case R.id.recipients_select_none_menu_id:
		case R.id.recipients_select_other_menu_id:
			doSelect(id);
			break;
		case R.id.recipients_select_menu_id:
			break;
		default:
			// lists
			String n = item.getTitle().toString();
			doLists(n);
			break;
		}
		return true;
	}

	private void doViewSelected() {
		showDialog(DIALOG_VIEWSELECTED);
	}

	@Override
	protected void onPrepareDialog(int id, Dialog dialog) {
		switch (id) {
		case DIALOG_VIEWSELECTED: {
			viewSelectedItems.clear();
			SparseBooleanArray ps = getListView().getCheckedItemPositions();
			int size = adapter.getCount();
			for (int i = 0; i < size; i++) {
				if (ps.get(i)) {
					EmailAddress ea = adapter.getItem(i);
					NameIndex ni = new NameIndex();
					//ni.name = ea.toString();
					ni.name = ea.address + "\t" + (ea.name == null ? "" : ea.name);
					ni.pos = i;
					viewSelectedItems.add(ni);
				}
			}
			break;
		}
		}
	}

	@Override
	public boolean onPrepareOptionsMenu(Menu menu) {
		boolean sel = hasSelected();
		
		viewMenuItem.setEnabled(sel);
		//
//		ArrayList<String> l = getListNames();
//		int size = l.size();
//		Menu sub = selectMenuItem.getSubMenu();
//		sub.setGroupVisible(R.id.SELECT_MENU, true);
//		sub.setGroupVisible(R.id.LIST_MENU, size > 0);
//		sub.removeGroup(R.id.LIST_MENU);
//		for (int i = 0; i < size; i++) {
//			sub.add(R.id.LIST_MENU, Menu.NONE, i, l.get(i));
//		}
		//
		return true;
	}

	@Override
	public Object onRetainNonConfigurationInstance() {
		Object[] obj = new Object[3];
		obj[0] = listname;
		obj[1] = getSelectedEmails();
		obj[2] = addresses;
		return obj;
	}

//	private ArrayList<String> getListNames() {
//		ArrayList<String> lists = new ArrayList<String>();
//		ContactUtils.loadMailLists(this, lists);
//		return lists;
//	}

	private void refreshUi(ListView v, boolean show, String name) {
		int sc = getSelectedCount();
		updateTitle(sc, name);
		showOrHideActions(show && sc > 0);
		v.requestLayout();
	}

	private void showOrHideActions(boolean b) {
		if (b) {
			showActions();
		} else {
			hideActions();
		}
	}
	
//
//	private void toast(int resId, int duration) {
//		Toast.makeText(this, resId, duration).show();
//	}
//
//	private void toast(int resId, String arg, int duration) {
//		CharSequence text = getString(resId, arg);
//		Toast.makeText(this, text, duration).show();
//	}

	private void updateTitle(int sc, String ln) {
		int tc = getCount();
		//String t = (ln == null ? getString(R.string.title_my_friends_nolist,
		//		sc, tc) : getString(R.string.title_my_friends, sc, tc, ln));
		setTitle(getString(R.string.title_my_friends_perm, sc, tc));
	}
}